home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 430_01 / m68kdis / afline.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-29  |  4.5 KB  |  218 lines

  1. /*
  2.  *                 Author:  Christopher G. Phillips
  3.  *              Copyright (C) 1994 All Rights Reserved
  4.  *
  5.  *                              NOTICE
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and
  8.  * its documentation for any purpose and without fee is hereby granted
  9.  * provided that the above copyright notice appear in all copies and
  10.  * that both the copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * The author makes no representations about the suitability of this
  14.  * software for any purpose.  This software is provided ``as is''
  15.  * without express or implied warranty.
  16.  */
  17.  
  18. /*
  19.  * The functions in this file customize the behavior of m68kdis
  20.  * to take certain word values as acceptable A-line and F-line
  21.  * instructions and whether any of these unconditionally change PC.
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <ctype.h>
  28. #include "dis.h"
  29.  
  30. #define F    0
  31. #define A    1
  32.  
  33. struct afinst {
  34.     m68kword    inst;
  35.     char        *name;
  36. };
  37.  
  38. static size_t    njinsts = 0;
  39. static m68kword    *jinsts = NULL;
  40.  
  41. /*
  42.  * Read through ``jfile'' and collect instruction values in ``jinsts''.
  43.  */
  44. static void
  45. readjfile(void)
  46. {
  47.     FILE        *jfp;
  48.     char        buf[80];
  49.     char        *cp;
  50.     m68kword    ul;
  51.     m68kword    *jtmp;
  52.  
  53.     if (jfp = fopen(jfile, "r")) {
  54.         while (fgets(buf, sizeof buf, jfp)) {
  55.             buf[strlen(buf) - 1] = '\0'; /* zap '\n' */
  56.             ul = strtoul(buf, &cp, 16);
  57.             if (cp == buf
  58.               || !((ul >= 0xa000 && ul <= 0xafff)
  59.               || (ul >= 0xf000 && ul <= 0xffff))) {
  60.                 fprintf(stderr, "%s: File %s: bad inst: %s\n",
  61.                   sfile, jfile, buf);
  62.                 continue;
  63.             }
  64.             if ((jtmp = realloc(jinsts,
  65.               ++njinsts * sizeof(*jinsts))) == NULL) {
  66.                 if (jtmp)
  67.                     jinsts = jtmp;
  68.                 perror("realloc");
  69.                 (void)fclose(jfp);
  70.                 return;
  71.             } else {
  72.                 jinsts = jtmp;
  73.                 jinsts[njinsts - 1] = ul;
  74.             }
  75.         }
  76.         (void)fclose(jfp);
  77.     } else
  78.         perror(jfile);
  79. }
  80.  
  81. /*
  82.  * Test whether ``word'' matches an instruction value in ``jfile''.
  83.  */
  84. static int
  85. itsajinst(m68kword word)
  86. {
  87.     size_t    i;
  88.  
  89.     for (i = 0; i < njinsts; i++)
  90.         if (word == jinsts[i])
  91.             return 1;
  92.  
  93.     return 0;
  94. }
  95.  
  96. /*
  97.  * Test whether ``word'' is a valid A- or F-line instruction,
  98.  * reading ``[af]file'' as necessary.
  99.  */
  100. static char *
  101. validafinst(int anotf, m68kword word)
  102. {
  103.     static int        fileread[2] = { 0, 0 };
  104.     static size_t        ninsts[2] = { 0, 0 };
  105.     static struct afinst    *afinsts[2] = { NULL, NULL };
  106.     struct afinst        *aftmp;
  107.     size_t            i;
  108.     static int        jfileread = 0;
  109.  
  110.     if (anotf && !afile || !anotf && !ffile)
  111.         return NULL;
  112.  
  113.     /*
  114.      * Read ``jfile'' if necessary.
  115.      */
  116.     if (jfile && !jfileread) {
  117.         readjfile();
  118.         jfileread = 1;
  119.     }
  120.  
  121.     /*
  122.      * Read ``[af]file'' if necessary, collecting the values
  123.      * in ``[af]insts'' and then sorting them.
  124.      */
  125.     if (!fileread[anotf]) {
  126.         FILE    *afp;
  127.  
  128.         fileread[anotf] = 1;
  129.         if (afp = fopen(anotf ? afile : ffile, "r")) {
  130.             char        afbuf[80];
  131.             m68kword    ul;
  132.             char        *cp;
  133.  
  134.             while (fgets(afbuf, sizeof afbuf, afp)) {
  135.                 afbuf[strlen(afbuf) - 1] = '\0'; /* zap '\n' */
  136.                 ul = strtoul(afbuf, &cp, 16);
  137.                 if (cp == afbuf
  138.                   || (anotf && (ul < 0xa000 || ul > 0xafff))
  139.                   || (!anotf && (ul < 0xf000 || ul > 0xffff))) {
  140.                     fprintf(stderr,
  141.                       "%s: File %s: bad inst: %s\n", sfile,
  142.                         anotf ? afile : ffile, afbuf);
  143.                     continue;
  144.                 }
  145.  
  146.                 /*
  147.                  * Find instruction-string.
  148.                  * Use "UNKNOWN" if not given.
  149.                  */
  150.                 cp--;
  151.                 while (*++cp && isspace(*cp))
  152.                     ;
  153.                 if (!cp)
  154.                     cp = "UNKNOWN";
  155.  
  156.                 if ((aftmp = realloc(afinsts[anotf],
  157.                   ++ninsts[anotf] * sizeof(*afinsts[anotf])))
  158.                   == NULL
  159.                   || (aftmp[ninsts[anotf] - 1].name
  160.                   = malloc(strlen(cp) + 1)) == NULL) {
  161.                     if (aftmp)
  162.                         afinsts[anotf] = aftmp;
  163.                     perror("realloc");
  164.                     return NULL;
  165.                 } else {
  166.                     afinsts[anotf] = aftmp;
  167.                     afinsts[anotf][ninsts[anotf] - 1].inst
  168.                       = ul;
  169.                     strcpy(
  170.                      afinsts[anotf][ninsts[anotf] - 1].name,
  171.                      cp);
  172.                 }
  173.             }
  174.             (void)fclose(afp);
  175.         } else
  176.             perror(anotf ? afile : ffile);
  177.     }
  178.     for (i = 0; i < ninsts[anotf]; i++)
  179.         if (word == afinsts[anotf][i].inst)
  180.             return afinsts[anotf][i].name;
  181.  
  182.     return NULL;
  183. }
  184.  
  185. /*
  186.  * Verify whether ``word'' is an acceptable A-line instruction.
  187.  * Print as necessary.
  188.  */
  189. void
  190. aline(m68kword word)
  191. {
  192.     char    *cp;
  193.  
  194.     if (cp = validafinst(A, word)) {
  195.         instprint(ops2f(0), cp);
  196.         valid = 1;
  197.         if (itsajinst(word))
  198.             flags |= ISJMP;
  199.     }
  200. }
  201.  
  202. /*
  203.  * Verify whether ``word'' is an acceptable F-line instruction.
  204.  * Print as necessary.
  205.  */
  206. void
  207. fline(m68kword word)
  208. {
  209.     char    *cp;
  210.  
  211.     if (cp = validafinst(F, word)) {
  212.         instprint(ops2f(0), cp);
  213.         valid = 1;
  214.         if (itsajinst(word))
  215.             flags |= ISJMP;
  216.     }
  217. }
  218.